﻿using Nomo.CoreModule;

namespace Nomo.UnityCoreModule
{
    /// <summary>
    /// Unity 日志记录器。
    /// </summary>
    public class UnityLogger : ILogger
    {
        /// <summary>
        /// 初始化 <see cref="UnityLogger"/> 类的新实例。
        /// </summary>
        public UnityLogger()
        {
            UnityEngine.Application.logMessageReceived += OnLogMessageReceived;
            if (System.IO.File.Exists(Common.LogPath))
            {
                System.IO.File.Delete(Common.LogPath);
            }
            using (System.IO.File.Create(Common.LogPath)) { }
            if (System.IO.File.Exists(Common.LogPath))
            {
                Log.Info($"创建日志文件成功，路径 : {Common.LogPath} .");
            }
            else
            {
                Log.Error($"创建日志文件成功，路径 : {Common.LogPath} .");
            }
        }

        /// <inheritdoc />
        ~UnityLogger()
        {
            UnityEngine.Application.logMessageReceived -= OnLogMessageReceived;
        }

        void ILogger.Info(object message)
        {
            UnityEngine.Debug.Log(message);
        }

        void ILogger.Warning(object message)
        {
            UnityEngine.Debug.LogWarning(message);
        }

        void ILogger.Error(object message)
        {
            UnityEngine.Debug.LogError(message);
        }

        /// <summary>
        /// 记录日志时。
        /// </summary>
        /// <param name="condition">信息。</param>
        /// <param name="stacktrace">堆栈。</param>
        /// <param name="type">日志类型。</param>
        private static void OnLogMessageReceived(string condition, string stacktrace, UnityEngine.LogType type)
        {
            switch (type)
            {
                case UnityEngine.LogType.Log:
                case UnityEngine.LogType.Warning:
                    break;
                case UnityEngine.LogType.Assert:
                case UnityEngine.LogType.Error:
                case UnityEngine.LogType.Exception:
                    if (System.IO.File.Exists(Common.LogPath))
                    {
                        using (var stream = new System.IO.FileStream(Common.LogPath, System.IO.FileMode.Append))
                        {
                            var buffer = System.Text.Encoding.UTF8.GetBytes(
                                $@"[{System.DateTime.Now:yyyy/MM/dd HH:mm:ss}]{type}
{condition}
{nameof(stacktrace)} : {(!string.IsNullOrEmpty(stacktrace) ? stacktrace : System.Environment.StackTrace)}"
                            );

                            stream.Write(buffer, 0, buffer.Length);
                        }
                    }

                    break;
                default:
                    throw new System.ArgumentOutOfRangeException(nameof(type), type, null);
            }
        }
    }
}
